export class MockSSEResponse {
  private controller!: ReadableStreamDefaultController<Uint8Array>;
  private encoder = new TextEncoder();
  private stream: ReadableStream<Uint8Array>;
  private error: boolean;

  /**
   * Constructs a new instance of the SSERequest class.
   *
   * @param data - The data to be pushed through the stream.
   * @param delay - The delay (in milliseconds) before starting to push data. Defaults to 300ms.
   * @param error - A boolean indicating whether to simulate an error condition. Defaults to false.
   *
   * The constructor initializes a ReadableStream that will push data after the specified delay,
   * unless an error condition is simulated. If an error is specified, the stream will not push any data.
   */
  constructor(
    private data: string,
    private delay: number = 300,
    error = false, // 新增参数，默认为false
  ) {
    this.error = error;

    this.stream = new ReadableStream({
      start: (controller) => {
        this.controller = controller;
        if (!this.error) {
          // 如果不是错误情况，则开始推送数据
          setTimeout(() => this.pushData(), this.delay); // 延迟开始推送数据
        }
      },
      cancel(reason) {
        console.log('Stream canceled', reason);
      },
    });
  }

  /**
   * Pushes data chunks to the controller at specified intervals.
   * If no more data is available, it closes the stream after a delay.
   * This method is responsible for managing the flow of data chunks
   * and ensuring that the stream is properly closed when all data has been sent.
   */
  private pushData() {
    if (this.data.length === 0) {
      this.controller.close();
      return;
    }
    try {
      const chunk = this.data.slice(0, 1);
      this.data = this.data.slice(1);

      this.controller.enqueue(this.encoder.encode(chunk));

      if (this.data.length > 0) {
        setTimeout(() => this.pushData(), this.delay);
      } else {
        // 数据全部发送完毕后关闭流
        setTimeout(() => this.controller.close(), this.delay);
      }
    } catch {}
  }

  /**
   * Simulates a network response with an optional delay and error.
   * 
   * This method returns a Promise that resolves to a Response object after a specified delay.
   * If an error is set, it resolves with a 500 Internal Server Error response; otherwise, it resolves
   * with a response containing the stream data.
   * 
   * @returns {Promise<Response>} A promise that resolves to a Response object.
   */
  getResponse(): Promise<Response> {
    return new Promise((resolve) => {
      // 使用setTimeout来模拟网络延迟
      setTimeout(() => {
        if (this.error) {
          const errorResponseOptions = { status: 500, statusText: 'Internal Server Error' };

          // 返回模拟的网络错误响应，这里我们使用500状态码作为示例
          resolve(new Response(null, errorResponseOptions));
        } else {
          resolve(new Response(this.stream));
        }
      }, this.delay); // 使用构造函数中设置的delay值作为延迟时间
    });
  }
}
